﻿using System;
using System.Collections;
using System.Configuration.Install;
using System.IO;
using System.Reflection;
using System.ServiceProcess;
using System.Windows.Forms;
using Microsoft.Win32;

namespace Hongwei.AS3PolicyServer.Server.Actions
{
    public static class Service
    {
        private const string SERVICE_NAME = "AS3 Policy Service";

        public static ServiceControllerStatus Status
        {
            get
            {
                using (ServiceController sc = new ServiceController(SERVICE_NAME))
                {
                    return sc.Status;
                }
            }
        }

        public static bool Check()
        {
            using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\" + SERVICE_NAME))
            {
                return null != rk;
            }
        }

        public static bool Install()
        {
            if (Check()) return true;

            try
            {
                AssemblyInstaller assemblyInstaller = new AssemblyInstaller(Assembly.GetExecutingAssembly(), new string[] { });
                TransactedInstaller transactedInstaller = new TransactedInstaller();
                transactedInstaller.Installers.Add(assemblyInstaller);
                transactedInstaller.Install(new Hashtable());

                using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\" + SERVICE_NAME, true))
                {
                    string imagePath = Convert.ToString(rk.GetValue("ImagePath"));
                    rk.SetValue("ImagePath", imagePath + " -s");
                }

                return true;
            }
            catch (Exception e)
            {
                using (FileStream fs = new FileStream(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "AS3PS.Error.log"), FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
                {
                    fs.Position = fs.Length;

                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.WriteLine("{0} - Message: {1}", DateTime.Now, e.Message);
                        sw.WriteLine("{0} - Source: {1}", DateTime.Now, e.Source);
                        sw.WriteLine("{0} - StackTrace: {1}", DateTime.Now, e.StackTrace);
                    }
                }

                return false;
            }
        }

        public static bool Uninstall()
        {
            if (!Check()) return true;

            try
            {
                AssemblyInstaller assemblyInstaller = new AssemblyInstaller(Assembly.GetExecutingAssembly(), new string[] { });
                TransactedInstaller transactedInstaller = new TransactedInstaller();
                transactedInstaller.Installers.Add(assemblyInstaller);
                transactedInstaller.Uninstall(null);

                return true;
            }
            catch (Exception e)
            {
                using (FileStream fs = new FileStream(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "AS3PS.Error.log"), FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
                {
                    fs.Position = fs.Length;

                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.WriteLine("{0} - Message: {1}", DateTime.Now, e.Message);
                        sw.WriteLine("{0} - Source: {1}", DateTime.Now, e.Source);
                        sw.WriteLine("{0} - StackTrace: {1}", DateTime.Now, e.StackTrace);
                    }
                }

                return false;
            }
        }

        public static void Start()
        {
            using (ServiceController sc = new ServiceController(SERVICE_NAME))
            {
                sc.Start();
            }
        }

        public static void Stop()
        {
            using (ServiceController sc = new ServiceController(SERVICE_NAME))
            {
                sc.Stop();
            }
        }
    }
}
